// src/hooks/useEchartNeed.ts

import { onMounted, onBeforeUnmount, onActivated, onDeactivated } from "vue";
import type { Ref } from "vue";
import * as echarts from "echarts/core"; // 只引入核心包
import type { EChartsOption } from "echarts";
import { debounce } from "lodash-es"; // 引入防抖函数，优化 resize


// 定义 ECharts 组件/图表类型
// ECharts 的 use 方法接收一个数组，这里定义其元素类型
type EchartComponent = Parameters<typeof echarts.use>[0];

/**
 * @description 使用 Echarts (支持按需引入)
 * @param {Ref<HTMLElement | undefined>} elementRef Echarts 挂载的 DOM 元素
 * @param {Ref<EChartsOption>} options Echarts 配置项 (建议使用 ref 以便响应式更新)
 * @param {EchartComponent} components Echarts 需要按需引入的组件和图表
 */
export const useEchartsNeed = (
	elementRef: Ref<HTMLElement | undefined>,
	options: Ref<EChartsOption>,
	components: EchartComponent
) => {
	// 注册 ECharts 组件
	echarts.use(components);

	let myChart: echarts.ECharts | null = null;

	// 使用 lodash-es 的 debounce 来创建防抖函数
	// 避免在窗口大小快速变化时频繁触发 resize，提升性能
	const echartsResize = debounce(() => {
		myChart?.resize();
	}, 300); // 300ms 的防抖延迟

	const initChart = () => {
		if (!elementRef.value) return;
		// 销毁旧实例，防止内存泄漏
		myChart?.dispose();
		// 初始化新实例
		myChart = echarts.init(elementRef.value, undefined, { renderer: 'canvas' }); // 明确使用 canvas
		// 设置配置项
		if (options.value) {
			myChart.setOption(options.value);
		}
		// 监听窗口大小变化
		window.addEventListener("resize", echartsResize);
	};

	// 监听 options 的变化，自动更新图表
	// watch(options, () => {
	//   if (myChart) {
	//     myChart.setOption(options.value);
	//   }
	// }, { deep: true });

	onMounted(initChart);

	onActivated(() => {
		myChart?.resize();
		window.addEventListener("resize", echartsResize);
	});

	onDeactivated(() => {
		window.removeEventListener("resize", echartsResize);
	});

	onBeforeUnmount(() => {
		window.removeEventListener("resize", echartsResize);
		myChart?.dispose();
	});

	// 返回 setOption 方法，允许外部动态更新图表
	const setOption = (newOptions: EChartsOption) => {
		if (myChart) {
			myChart.setOption(newOptions);
		}
	};


  watch(
		options,
		(newOptions) => {
			if (myChart) {
				// 当 options 变化时，用新配置更新图表
				myChart.setOption(newOptions);
			}
		},
		{
			// deep: true 是必须的，因为我们通常是修改 options 对象的内部属性
			// 而不是替换整个对象
			deep: true,
		}
	);
	
	return {
		setOption
	};
};
